<?php
/**
 * PHPWord
 *
 * Copyright (c) 2011 PHPWord
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @category   PHPWord
 * @package    PHPWord
 * @copyright  Copyright (c) 010 PHPWord
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
 * @version    Beta 0.6.3, 08.07.2011
 */


/**
 * PHPWord_DocumentProperties
 *
 * @category   PHPWord
 * @package    PHPWord
 * @copyright  Copyright (c) 2009 - 2011 PHPWord (http://www.codeplex.com/PHPWord)
 */
class PHPWord_Template {
    
    /**
     * ZipArchive
     * 
     * @var ZipArchive
     */
    private $_objZip;
    
    /**
     * Temporary Filename
     * 
     * @var string
     */
    private $_tempFileName;
    
    /**
     * Document XML
     * 
     * @var string
     */
    private $_documentXML;

    /**
     * [$_isdoc 当前是哪个文档]
     * @var [type]
     */
    private $_isdoc;
    
    
    /**
     * Create a new Template Object
     * 
     * @param string $strFilename
     */
    public function __construct($strFilename) {
        $path = dirname($strFilename);
        $this->_tempFileName = $path.DIRECTORY_SEPARATOR.time().'.docx';
        
        copy($strFilename, $this->_tempFileName); // Copy the source File to the temp File

        $this->_objZip = new ZipArchive();
        $this->_objZip->open($this->_tempFileName);
        
        $this->_documentXML = $this->_objZip->getFromName('word/document.xml');
        $this->_isdoc = "word/document.xml";
    }

    /**
     * 设置操作哪一个xml文档，默认是document.xml
     */
    public function setDocument($filename_str){
        $a = array();
        $a['body'] = 'word/document.xml';
        $a['header'] = 'word/header1.xml';
        $this->_objZip->addFromString($this->_isdoc, $this->_documentXML);
        $this->_documentXML = $this->_objZip->getFromName($a[$filename_str]);
        $this->_isdoc = $a[$filename_str];
    }

    /**
     * [getField 获取到word模板字符串中的字段，并返回]
     * @return [array] [array]
     */
    public function getField(){
        $a = '\$\{';
        $b = '\}';
        $arr = array();

        $pattern = '/'.$a.'(.*)'.$b.'/U';

        preg_match_all($pattern,$this->_documentXML, $matches);
       
        
        array_push($arr, $matches[1]);

        $a = '\$l\{';
        $b = '\}';

        $pattern = '/'.$a.'(.*)'.$b.'/U';

         preg_match_all($pattern,$this->_documentXML, $matches);
       
          array_push($arr,$this->loopfieldstoarray($matches[1]));
          // array_push($arr, $matches[1]);
      
         
             // Close zip file
        if($this->_objZip->close() === false) {
            throw new Exception('Could not close zip file.');
        }else{
            if(!unlink($this->_tempFileName)){
                echo '删除缓存文件失败。请手动操作。';
            }
        }
        return $arr;

    }

    protected function loopfieldstoarray($arr){
        $loop = '';
        $a = array();
        foreach ($arr as $key => $value) {
           if($loop == ''){
            $b = array();
            $loop = $value;
            array_push($b, $value);
            array_push($b, array());
           }elseif($value != '/'.$loop){
            array_push($b[1], $value);
           }elseif($value == '/'.$loop){
            $loop = '';
            array_push($a, $b);
           }
        }
       return $a;
    }
    
    /**
     * Set a Template value
     * 
     * @param mixed $search
     * @param mixed $replace
     */
    public function setValue($search, $replace) {
        if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
            $search = '${'.$search.'}';
        }
        
        if(!is_array($replace)) {
            //$replace = utf8_encode($replace);
           $replace =mb_convert_encoding($replace, "utf-8",'auto');
          //$replace =iconv('gbk', 'utf-8', $replace);
        }
        
        $this->_documentXML = str_replace($search, $replace, $this->_documentXML);
    }

// 遍历循环替换值，参数:搜索对象，基本数组（数组内部每项应为关联数组）
    public function setLoop($search,$arr){

        if(substr($search,0,3) !== '$l{' && substr($search,-1) !== '}'){
             $search_end = '$l{/'.$search.'}';
            $search = '$l{'.$search.'}';

            
        }

        if(is_array($arr)){
        // 找到循环体内的字符串（包含了很多其他标签）

        $start = strpos($this->_documentXML,$search);
        $end = strpos($this->_documentXML,$search_end);

        if(!$start || !$end){
            // echo "没有该循环体，或标签有误！".$search."</br>";
            return;
        }
        $repl = substr($this->_documentXML, $start,$end-$start);
        $del_search_str = $repl;
        // 循环开始标签字符串后的包裹循环字符串的标签内容。
        $daa = substr($del_search_str, 0,strpos($del_search_str,'</w:p>')+6);
      
        $daad = strripos(substr($this->_documentXML,0,$start), '<w:p ');
        $daad = substr(substr($this->_documentXML,0,$start), $daad);
       // 循环开始标记，含包裹标签
        $daad = $daad.$daa;

        // 删除结束标签
        $csd = strripos($del_search_str, '<w:p ');

        $csd = substr($del_search_str, $csd);

        $ades = strpos(substr($this->_documentXML,$end),'</w:p>');
       
        $ades = substr(substr($this->_documentXML,$end), 0,$ades+6);
        $ades = $csd.$ades;
      
      
        // 将体内字符串再截取，只需要循环内容及包含这些内容的标签
        $start = strpos($repl, '<w:tbl');
        if(!$start){
            // 循环段落
            $start = strpos($repl, '<w:p');
            $end = strripos($repl, '</w:p>');
            $repl = substr($repl, $start,$end-$start+6);

        }else{
             // 循环表格
              $end = strripos($repl, '</w:tbl>');
              $repl = substr($repl, $start,$end-$start+8);
        }
       
      
      

        $aa = '';
        for($i=0;$i<count($arr);$i++){
            $bb = $repl;
            foreach ($arr[$i] as $key => $value) {
              $bb = str_replace('$l{'.$key.'}', $value, $bb);
            }
             $bb = str_replace('$l{indexa}', $i+1, $bb);
            $aa .= $bb;
        }
            

         $this->_documentXML =   str_replace($repl, $aa, $this->_documentXML);
         $this->_documentXML =   str_replace($daad,'', $this->_documentXML);
         $this->_documentXML =   str_replace($ades,'', $this->_documentXML);

        }else{
            // echo "is not array";
            return;
        }
    }



/**
 * set image 
 */

    public function setImg($search, $replace){
        // $this->_objZip->deleteName('word/media/image1.jpeg');
        $this->_objZip->addFile($replace,$search);
    }
    


    /**
     * Save Template
     * 
     * @param string $strFilename
     */
    public function save($strFilename) {
        if(file_exists($strFilename)) {
            unlink($strFilename);
        }
        
        $this->_objZip->addFromString($this->_isdoc, $this->_documentXML);
        
        // Close zip file
        if($this->_objZip->close() === false) {
            throw new Exception('Could not close zip file.');
        }
        
      return rename($this->_tempFileName, $strFilename);
    }
}
?>